package comparesions

import (
	"gvm/instructions/base"
	"gvm/rtda"
	"reflect"
	"strings"
)

type EQ struct {
}

type NE struct {
}

type LT struct {
}

type GT struct {
}

type LE struct {
}

type GE struct {
}

// Branch if int comparison with zero succeeds
type IF[T EQ | NE | LT | LE | GE | GT] struct{ base.BranchInstruction }

func (self *IF[T]) Execute(jFrame *rtda.JFrame) {
	val := jFrame.OperandStack().PopInt()
	e := reflect.TypeOf(self).Elem().String()
	etype := strings.ReplaceAll(strings.Split(e, "[")[1], "]", "")
	switch etype {
	case "EQ":
		if val == 0 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "NE":
		if val != 0 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "LT":
		if val < 0 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "LE":
		if val <= 0 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "GT":
		if val > 0 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "GE":
		if val >= 0 {
			base.Branch(jFrame, self.Offset)
		}
		break
	}
}

type IFEQ struct {
	IF[EQ]
}

type IFNE struct {
	IF[NE]
}

type IFLT struct {
	IF[LT]
}
type IFLE struct {
	IF[LE]
}

type IFGT struct {
	IF[GE]
}
type IFGE struct {
	IF[GE]
}
